from django.shortcuts import render
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from .utils import OAuthQQ
from .exceptions import QQAPIException
from .models import OAuthQQUser
from rest_framework_jwt.views import api_settings
from . import serializers


# Create your views here.

# 第一大步
# 只负责拼接字符串, 不需要验证, 所以用APIView
# GET /oauth/qq/authorization/?next=xxx
# url(r'^qq.authorization/$', views.QQAuthURLView.as_view())
class QQAuthURLView(APIView):
    """
    获取QQ扫码登录界面的的url
    """

    def get(self, request):
        """
        提供用于qq登录的url
        """
        next = request.query_params.get('next')

        # 创建qq登录的工具类的对象
        oauth = OAuthQQ(state=next)
        # 生成QQ扫码登录的链接
        login_url = oauth.get_qq_login_url()
        return Response({'login_url': login_url})


# GET /oauth/qq/user/?code=xxx
# url(r'^qq/user/$', views.QQAuthUserView.as_view()),
class QQAuthUserView(GenericAPIView):
    """⽤户扫码登录的回调处理"""

    # 指定序列化器
    serializer_class = serializers.OAuthQQUserSerializer

    # 第二大步
    def get(self, request):
        # 提取code请求参数
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST)
        # 创建QQ登录的工具类对象
        oauth = OAuthQQ()
        try:
            # 使⽤code向QQ服务器请求access_token
            access_token = oauth.get_access_token(code)

            # 使⽤access_token向QQ服务器请求openid
            openid = oauth.get_openid(access_token)
        except QQAPIException:
            return Response({"message": "QQ服务器异常"}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 第三大步
        # 使⽤openid查询该QQ⽤户是否在美多商城中绑定过⽤户
        try:
            # oauth_user查出来的是一整条记录, OAuthQQUser的对象
            oauth_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果openid没绑定美多商城⽤户，创建⽤户并绑定到openid
            access_token_openid = OAuthQQ.generate_save_user_token(openid)

            return Response({"access_token": access_token_openid})
        else:
            # 如果openid已绑定美多商城⽤户，直接⽣成JWT token，并返回
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            # 获取关联openid的user
            user = oauth_user.user
            payload = jwt_payload_handler(user)

            token = jwt_encode_handler(payload)

            response = Response({
                "user_id": user.id,
                "username": user.username,
                "token": token
            })

            # 向前端相应token, user_id, username
            return response

    # 本次创建用户模型类有两个, 所以不使用CreateAPIView
    def post(self, request):
        """用户扫码登录的回调处理"""

        # 获取序列化器 , 注册的数据都在post请求的请求体里面
        serializer = self.get_serializer(data=request.data)
        # 开启校验
        serializer.is_valid(raise_exception=True)
        # 保存校验的数据 : create 会返回user
        user = serializer.save()

        # 生成已经登录的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            'token': token,
            'user_id': user.id,
            'username': user.username
        })
        return response
